# Create your views here.
import datetime
import logging

from rest_framework import filters
from rest_framework import viewsets
from rest_framework.response import Response
from rest_framework.decorators import action
from django.db import models
from django.db.models import Q
from utils.pagination import MyPageNumberPagination, PageNumberPagination
from .models import Tasks
from . import serializers
from django_filters import rest_framework as django_filters

logger = logging.getLogger('dev07')


class TasksFilter(django_filters.FilterSet):
    task_id = django_filters.CharFilter(field_name="task_id", lookup_expr="icontains")
    epic_name = django_filters.CharFilter(field_name="epic_name", lookup_expr="icontains")
    story_name = django_filters.CharFilter(field_name="story_name", lookup_expr="icontains")
    task_name = django_filters.CharFilter(field_name="task_name", lookup_expr="icontains")
    task_type = django_filters.CharFilter(field_name="task_type", lookup_expr="in", method="filter_task_type")
    project = django_filters.CharFilter(field_name="project", lookup_expr="icontains")
    status = django_filters.CharFilter(field_name="status", lookup_expr="in", method="filter_status")
    fc_responsible_person = django_filters.CharFilter(field_name="fc_responsible_person", lookup_expr="in", method="filter_responsible_person")
    fc_publish_version = django_filters.CharFilter(field_name="fc_publish_version", lookup_expr="icontains")
    product_manager = django_filters.CharFilter(field_name="product_manager", lookup_expr="in", method="filter_product_manager")
    fc_product_manager = django_filters.CharFilter(field_name="product_manager", lookup_expr="in", method="filter_product_manager")
    estimate_time = django_filters.NumberFilter(field_name="estimate_time", lookup_expr="exact")
    fc_plan_start_time_start = django_filters.DateFilter(field_name="fc_plan_start_time", lookup_expr="gte")
    fc_plan_start_time_end = django_filters.DateFilter(field_name="fc_plan_start_time", lookup_expr="lte")
    fc_plan_end_time_start = django_filters.DateFilter(field_name="fc_plan_end_time", lookup_expr="gte")
    fc_plan_end_time_start = django_filters.DateFilter(field_name="fc_plan_end_time", lookup_expr="lte")

    def filter_status(self, queryset, name, value):
        """处理多个状态值的筛选，支持逗号分隔的状态值"""
        if value:
            # 将逗号分隔的状态值转换为列表
            status_list = [status.strip() for status in value.split(',') if status.strip()]
            if status_list:
                return queryset.filter(status__in=status_list)
        return queryset

    def filter_responsible_person(self, queryset, name, value):
        """处理多个责任人的筛选，支持逗号分隔的责任人"""
        if value:
            # 将逗号分隔的责任人转换为列表
            responsible_person_list = [person.strip() for person in value.split(',') if person.strip()]
            if responsible_person_list:
                return queryset.filter(fc_responsible_person__in=responsible_person_list)
        return queryset

    def filter_product_manager(self, queryset, name, value):
        """处理多个产品经理的筛选，支持逗号分隔的产品经理和数组格式"""
        if value:
            # Django Filter会自动处理数组格式，直接使用即可
            # 但为了兼容逗号分隔的字符串格式，我们需要进行判断
            product_manager_list = value
            
            # 如果是字符串格式，转换为数组
            if isinstance(product_manager_list, str):
                product_manager_list = [pm.strip() for pm in product_manager_list.split(',') if pm.strip()]
            # 如果是单个值的列表，确保它是列表格式
            elif not isinstance(product_manager_list, list):
                product_manager_list = [str(product_manager_list)]
            
            # 过滤掉空值
            product_manager_list = [pm for pm in product_manager_list if pm and pm.strip()]
            
            if product_manager_list:
                return queryset.filter(product_manager__in=product_manager_list)
        return queryset

    def filter_task_type(self, queryset, name, value):
        """处理多个任务类型的筛选，支持逗号分隔的任务类型值"""
        if value:
            # 将逗号分隔的任务类型值转换为列表
            task_type_list = [task_type.strip() for task_type in value.split(',') if task_type.strip()]
            if task_type_list:
                return queryset.filter(task_type__in=task_type_list)
        return queryset

    class Meta:
        model = Tasks
        fields = ["task_id", "epic_name", "story_name", "task_name", "task_type", "project", "status",
                  "fc_responsible_person", "fc_publish_version", "product_manager", "estimate_time", "fc_plan_start_time", "fc_plan_end_time"]


class TasksViewSet(viewsets.ModelViewSet):
    """
    list:
    获取任务列表和工时统计

    retrieve:
    获取任务详情数据

    update:
    更新任务信息

    """
    queryset = Tasks.objects.all()
    serializer_class = serializers.SearchTasksModelSerailizer

    # filter_backends = [filters.SearchFilter, filters.OrderingFilter]
    filter_backends = [django_filters.DjangoFilterBackend, filters.OrderingFilter]
    filterset_class = TasksFilter
    # search_fields = ['=name', '=leader', '=id']
    ordering_fields = ['fc_plan_start_time', 'fc_plan_end_time']
    pagination_class = PageNumberPagination
    # permission_classes = [permissions.IsAuthenticated]
    
    def get_queryset(self):
        queryset = super().get_queryset()
        if self.request.query_params.get('task_start_data'):
            task_start_data = datetime.datetime.strptime(self.request.query_params.get('task_start_data'), '%Y-%m-%d').date()
            task_end_data = datetime.datetime.strptime(self.request.query_params.get('task_end_data'), '%Y-%m-%d').date()
            queryset = queryset.filter(
                Q(fc_plan_start_time__gte=task_start_data, fc_plan_start_time__lte=task_end_data) |
                Q(fc_plan_end_time__gte=task_start_data, fc_plan_end_time__lte=task_end_data)
            )
        return queryset
    
    def list(self, request, *args, **kwargs):
        # 获取过滤后的查询集
        queryset = self.filter_queryset(self.get_queryset())
        
        # 计算工时总和
        total_hours = queryset.aggregate(total=models.Sum('estimate_time'))['total'] or 0
        
        # 执行分页
        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            # 获取分页信息
            paginated_response = self.get_paginated_response(serializer.data)
            # 添加工时总和到响应中
            paginated_response.data['total_hours'] = float(total_hours)
            return paginated_response
        
        # 不分页的情况
        serializer = self.get_serializer(queryset, many=True)
        return Response({
            'results': serializer.data,
            'count': len(serializer.data),
            'total_hours': float(total_hours)
        })

    @action(detail=False, methods=['get'])
    def responsible_persons(self, request):
        """获取所有责任人列表"""
        responsible_persons = Tasks.objects.values_list('fc_responsible_person', flat=True).distinct()
        # 过滤掉空值并去除前后空格，然后去重
        responsible_persons = list(set([person.strip() for person in responsible_persons if person and person.strip()]))
        responsible_persons.sort()
        return Response({
            'results': responsible_persons,
            'count': len(responsible_persons)
        })

    @action(detail=False, methods=['get'])
    def product_managers(self, request):
        """获取所有产品经理列表"""
        product_managers = Tasks.objects.values_list('product_manager', flat=True).distinct()
        # 过滤掉空值并去除前后空格，然后去重
        product_managers = list(set([pm.strip() for pm in product_managers if pm and pm.strip()]))
        product_managers.sort()
        return Response({
            'results': product_managers,
            'count': len(product_managers)
        })

    @action(detail=False, methods=['get'])
    def task_statuses(self, request):
        """获取所有任务状态列表"""
        statuses = Tasks.objects.values_list('status', flat=True).distinct()
        # 过滤掉空值并去除前后空格，然后去重
        statuses = list(set([status.strip() for status in statuses if status and status.strip()]))
        statuses.sort()
        return Response({
            'results': statuses,
            'count': len(statuses)
        })

    @action(detail=False, methods=['get'])
    def task_types(self, request):
        """获取所有任务类型列表"""
        task_types = Tasks.objects.values_list('task_type', flat=True).distinct()
        # 过滤掉空值并去除前后空格，然后去重
        task_types = list(set([task_type.strip() for task_type in task_types if task_type and task_type.strip()]))
        task_types.sort()
        return Response({
            'results': task_types,
            'count': len(task_types)
        })
    
    @action(detail=False, methods=['get'])
    def publish_versions(self, request):
        """获取所有发布版本列表"""
        publish_versions = Tasks.objects.values_list('fc_publish_version', flat=True).distinct()
        # 过滤掉空值并去除前后空格，然后去重
        publish_versions = list(set([version.strip() for version in publish_versions if version and version.strip()]))
        publish_versions.sort()
        return Response({
            'results': publish_versions,
            'count': len(publish_versions)
        })
    
    @action(detail=False, methods=['get'])
    def human_resource_statistics(self, request):
        """获取人力统计信息：按照任务责任人分组，返回任务数和总工时"""
        # 构建查询集
        queryset = Tasks.objects.all()
        
        # 获取责任人筛选参数
        responsible_person = request.query_params.get('responsible_person')
        if responsible_person:
            # 支持逗号分隔的多个责任人
            responsible_person_list = [rp.strip() for rp in responsible_person.split(',') if rp.strip()]
            if responsible_person_list:
                queryset = queryset.filter(fc_responsible_person__in=responsible_person_list)
        
        # 获取史诗筛选参数
        epic_name = request.query_params.get('epic_name')
        if epic_name:
            queryset = queryset.filter(epic_name__icontains=epic_name)
        
        # 获取故事筛选参数
        story_name = request.query_params.get('story_name')
        if story_name:
            queryset = queryset.filter(story_name__icontains=story_name)
        
        # 获取版本筛选参数
        fc_publish_version = request.query_params.get('fc_publish_version')
        if fc_publish_version:
            # 支持逗号分隔的多个版本
            version_list = [version.strip() for version in fc_publish_version.split(',') if version.strip()]
            if version_list:
                queryset = queryset.filter(fc_publish_version__in=version_list)
        
        # 获取任务类型筛选参数
        task_type = request.query_params.get('task_type')
        if task_type:
            queryset = queryset.filter(task_type=task_type)
        
        # 获取任务预计开始时间范围筛选参数
        plan_start_time_start = request.query_params.get('plan_start_time_start')
        plan_start_time_end = request.query_params.get('plan_start_time_end')
        if plan_start_time_start:
            queryset = queryset.filter(fc_plan_start_time__gte=plan_start_time_start)
        if plan_start_time_end:
            queryset = queryset.filter(fc_plan_start_time__lte=plan_start_time_end)
        
        # 按责任人分组统计任务数和总工时
        statistics = queryset.values('fc_responsible_person').annotate(
            task_count=models.Count('id'),
            total_hours=models.Sum('estimate_time')
        ).order_by('-total_hours')
        
        # 格式化返回数据
        results = []
        # 计算所有责任人的总工时
        all_total_hours = 0.0
        for stat in statistics:
            # 过滤掉空的责任人
            if stat['fc_responsible_person']:
                total_hours = float(stat['total_hours']) if stat['total_hours'] else 0.0
                all_total_hours += total_hours
                results.append({
                    'responsible_person': stat['fc_responsible_person'].strip(),
                    'task_count': stat['task_count'],
                    'total_hours': total_hours
                })
        
        # 应用分页
        page = self.paginate_queryset(results)
        if page is not None:
            paginated_response = self.get_paginated_response(page)
            # 添加总工时到分页响应中
            paginated_response.data['total_hours'] = all_total_hours
            return paginated_response
        
        # 不分页的情况
        return Response({
            'results': results,
            'count': len(results),
            'total_hours': all_total_hours
        })